const shape = {
  Square: [
    [-16, -15, -6, -5]
  ],
  Z: [
    [-16, -15, -5, -4],
    [-24, -14, -15, -5]
  ],
  Twig: [[-25, -15, -5, 5], [-16, -15, -14, -13]],
  left7: [[-16, -15, -5, 5], [-14, -4, -5, -6], [6, 5, -5, -15], [4, -6, -5, -4]],
  right7: [[-14, -15, -5, 5], [6, -4, -5, -6], [4, 5, -5, -15], [-16, -6, -5, -4]],
  S: [[-15, -4, -5, -6], [-4, 5, -5, -15], [5, -6, -5, -4], [-6, -15, -5, 5]]
}
const shapeName = ['Square', 'Z', 'Twig', 'left7', 'right7', 'S']

const color = {
  Square: '#700',
  Z: '#008',
  Twig: '#689',
  left7: '#6c1',
  right7: '#16c',
  S: '#748'
}

export class Square {
  constructor(map, score) {
    this.map = map
    this.score = score
    this.shapeName = shapeName[Math.floor(shapeName.length * Math.random())]
    this.shape = shape[this.shapeName]
    this.p1 = this.shape[0][0]
    this.p2 = this.shape[0][1]
    this.p3 = this.shape[0][2]
    this.p4 = this.shape[0][3]
    this.timer = null
    this.color = color[this.shapeName]
    this.Y = 0
    this.X = 0
    this.index = 0
  }
  speedUp() {
    clearInterval(this.timer)
    this.timer = null
    return new Promise((resolve, reject) => {
      if (this.timer !== null) return;
      this.timer = setInterval(() => {
        if (this.stop() === true) {
          resolve()
          return
        } else if (this.stop() === "gameOver") {
          reject()
          return
        }
        this.remove()
        this.down()
        this.init()
      }, 30)
    })
  }
  rotation() {
    let i = this.index
    i++
    if (i === this.shape.length) i = 0
    if (this.map[this.shape[i][0] + this.X + this.Y] && rottt(this, this.shape[i][0] + this.X + this.Y) && this.map[this.shape[i][0] + this.X + this.Y].class === true) return
    if (this.map[this.shape[i][1] + this.X + this.Y] && rottt(this, this.shape[i][1] + this.X + this.Y) && this.map[this.shape[i][1] + this.X + this.Y].class === true) return
    if (this.map[this.shape[i][2] + this.X + this.Y] && rottt(this, this.shape[i][2] + this.X + this.Y) && this.map[this.shape[i][2] + this.X + this.Y].class === true) return
    if (this.map[this.shape[i][3] + this.X + this.Y] && rottt(this, this.shape[i][3] + this.X + this.Y) && this.map[this.shape[i][3] + this.X + this.Y].class === true) return
    if (this.shapeName === 'Twig' && this.X === 4) return
    this.remove()
    this.index++
    if (this.index === this.shape.length) this.index = 0
    if (this.shapeName === 'Z' && this.X === -5) this.X++
    if (this.shapeName === 'Twig' && this.X === -5) this.X++
    if (this.shapeName === 'Twig' && this.X === 3) this.X--
    if (this.shapeName === 'right7' && this.X === 4) this.X--
    if (this.shapeName === 'right7' && this.X === -5) this.X++
    if (this.shapeName === 'left7' && this.X === 4) this.X--
    if (this.shapeName === 'left7' && this.X === -5) this.X++
    if (this.shapeName === 'S' && this.X === 4) this.X--
    if (this.shapeName === 'S' && this.X === -5) this.X++
    this.p1 = this.shape[this.index][0] + this.X + this.Y
    this.p2 = this.shape[this.index][1] + this.X + this.Y
    this.p3 = this.shape[this.index][2] + this.X + this.Y
    this.p4 = this.shape[this.index][3] + this.X + this.Y
    this.init()
  }
  moveLeft() {
    if (this.p1 === 0 || this.p2 === 0 || this.p3 === 0 || this.p4 === 0) return
    if (this.p1 % 10 === 0 || this.p2 % 10 === 0 || this.p3 % 10 === 0 || this.p4 % 10 === 0) return
    // if (this.map[this.p3 - 1] && this.map[this.p3 - 1].class == true) return
    let arr = paixL(this.p1, this.p2, this.p3, this.p4)
    for (let i in arr) {
      if (this.map[arr[i] - 1] && this.map[arr[i] - 1].class === true) return
    }
    this.remove()
    this.p1 -= 1
    this.p2 -= 1
    this.p3 -= 1
    this.p4 -= 1
    this.init()
    this.X--
  }
  moveRight() {
    if (this.p1 === 9 || this.p2 === 9 || this.p3 === 9 || this.p4 === 9) return
    if ((this.p1 - 9) % 10 === 0 || (this.p2 - 9) % 10 === 0 || (this.p3 - 9) % 10 === 0 || (this.p4 - 9) % 10 === 0) return;
    let arr = paixR(this.p1, this.p2, this.p3, this.p4)
    for (let i in arr) {
      if (this.map[arr[i] + 1] && this.map[arr[i] + 1].class === true) return
    }
    this.remove()
    this.p1 += 1
    this.p2 += 1
    this.p3 += 1
    this.p4 += 1
    this.init()
    this.X++
  }
  down() {
    this.p1 += 10
    this.p2 += 10
    this.p3 += 10
    this.p4 += 10
    this.Y += 10
  }
  remove() {
    if (this.map[this.p1]) {
      this.map[this.p1].color = ""
      this.map[this.p1].class = false
    }
    if (this.map[this.p2]) {
      this.map[this.p2].color = ""
      this.map[this.p2].class = false
    }
    if (this.map[this.p3]) {
      this.map[this.p3].color = ""
      this.map[this.p3].class = false
    }
    if (this.map[this.p4]) {
      this.map[this.p4].color = ""
      this.map[this.p4].class = false
    }
  }
  init() {
    if (this.map[this.p1]) {
      this.map[this.p1].color = this.color
      this.map[this.p1].class = true
    }
    if (this.map[this.p2]) {
      this.map[this.p2].color = this.color
      this.map[this.p2].class = true
    }
    if (this.map[this.p3]) {
      this.map[this.p3].color = this.color
      this.map[this.p3].class = true
    }
    if (this.map[this.p4]) {
      this.map[this.p4].color = this.color
      this.map[this.p4].class = true
    }
  }
  start() {
    return new Promise((resolve, reject) => {
      if (this.timer !== null) return;
      this.timer = setInterval(() => {
        if (this.stop() === true) {
          resolve()
          return
        } else if (this.stop() === "gameOver") {
          reject()
          return
        }
        this.remove()
        this.down()
        this.init()
      }, 800)
    })
  }
  stop() {
    if (this.p1 >= 150 || this.p2 >= 150 || this.p3 >= 150 || this.p4 >= 150) {
      clearInterval(this.timer)
      this.timer = null
      clear(this)
      return true
    }
    let arr = paixD(this.p1, this.p2, this.p3, this.p4)

    for (let i in arr) {
      if (this.map[arr[i] + 10].class === true) {
        if (this.over()) return "gameOver"
        clearInterval(this.timer)
        this.timer = null
        clear(this)
        return true
      }
    }
    return false
  }
  over() {
    if (this.p1 < 0 || this.p2 < 0 || this.p3 < 0 || this.p4 < 0) return true
  }
}
function clear(m_that) {
  let i_arr = []
  for (let i = 15; i >= 0; i--) {
    let count = 0;
    for (let j = 0; j < 10; j++) {
      if (m_that.map[i * 10 + j].class === true) {
        count++
      }
      if (count === 10) {
        console.log("进入i===" + i)
        i_arr.push(i)
      }
    }
  }
  if (i_arr.length !== 0) {
    enterRemove(m_that, i_arr)
  }
}
function enterRemove(m_that, i_arr) {
  let arr = i_arr
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < 10; j++) {
      m_that.map[arr[i] * 10 + j].class = false
      m_that.map[arr[i] * 10 + j].color = ""
    }
    m_that.map.splice(arr[i] * 10, 10)
  }

  for (let x = 0; x < arr.length * 10; x++) {
    m_that.map.unshift({ class: false })
  }
  switch (arr.length) {
    case 1: {
      m_that.score.num += 100
      break;
    }
    case 2: {
      m_that.score.num += 300
      break;
    }
    case 3: {
      m_that.score.num += 600
      break;
    }
    case 4: {
      m_that.score.num += 1000
      break;
    }
  }

}

function paixD(p1, p2, p3, p4) {
  let arr = []
  if (p2 !== (p1 + 10) && p3 !== (p1 + 10) && p4 !== (p1 + 10) && p1 > 0) {
    arr.push(p1)
  }
  if (p1 !== (p2 + 10) && p3 !== (p2 + 10) && p4 !== (p2 + 10) && p2 > 0) {
    arr.push(p2)
  }
  if (p1 !== (p3 + 10) && p2 !== (p3 + 10) && p4 !== (p3 + 10) && p3 > 0) {
    arr.push(p3)
  }
  if (p1 !== (p4 + 10) && p2 !== (p4 + 10) && p3 !== (p4 + 10) && p4 > 0) {
    arr.push(p4)
  }
  return arr
}
function paixL(p1, p2, p3, p4) {
  let arr = []
  if (p2 !== (p1 - 1) && p3 !== (p1 - 1) && p4 !== (p1 - 1)) {
    arr.push(p1)
  }
  if (p1 !== (p2 - 1) && p3 !== (p2 - 1) && p4 !== (p2 - 1)) {
    arr.push(p2)
  }
  if (p1 !== (p3 - 1) && p2 !== (p3 - 1) && p4 !== (p3 - 1)) {
    arr.push(p3)
  }
  if (p1 !== (p4 - 1) && p2 !== (p4 - 1) && p3 !== (p4 - 1)) {
    arr.push(p4)
  }
  return arr
}
function paixR(p1, p2, p3, p4) {
  let arr = []
  if (p2 !== (p1 + 1) && p3 !== (p1 + 1) && p4 !== (p1 + 1)) {
    arr.push(p1)
  }
  if (p1 !== (p2 + 1) && p3 !== (p2 + 1) && p4 !== (p2 + 1)) {
    arr.push(p2)
  }
  if (p1 !== (p3 + 1) && p2 !== (p3 + 1) && p4 !== (p3 + 1)) {
    arr.push(p3)
  }
  if (p1 !== (p4 + 1) && p2 !== (p4 + 1) && p3 !== (p4 + 1)) {
    arr.push(p4)
  }
  return arr
}
function rottt(m_that, e) {
  if (m_that.p1 === e && m_that.map[m_that.p1].class == true) return false
  if (m_that.p2 === e && m_that.map[m_that.p2].class == true) return false
  if (m_that.p3 === e && m_that.map[m_that.p3].class == true) return false
  if (m_that.p4 === e && m_that.map[m_that.p4].class == true) return false
  return true
}